package com.md.config;


import com.google.common.collect.Lists;
import com.md.client.OpenApiClient;
import com.md.request.ApiRequest;
import com.md.util.ObjectUtil;
import com.md.util.SpringContextUtil;
import com.md.value.ApiTypeEnum;
import com.md.value.enums.ApiMethodEnum;
import com.md.value.enums.AuthEnum;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.util.List;
import java.util.Map;
import java.util.Optional;

@Component
@AllArgsConstructor
@Slf4j
public class SystemApiGenerate implements ApplicationListener<ApplicationReadyEvent> {
  private final SystemConfig systemConfig;
  private final ServerProperties serverProperties;

  @Override
  public void onApplicationEvent(@NonNull final ApplicationReadyEvent applicationReadyEvent) {
    initSystemApi();
  }

  public void initSystemApi() {
    if (ObjectUtil.isEmpty(systemConfig.getAppInfoId())) {
      return;
    }
    // 获取 RequestMappingHandlerMapping
    RequestMappingHandlerMapping handlerMapping = SpringContextUtil.getBean(RequestMappingHandlerMapping.class);

    // 获取所有的URL映射
    Map<RequestMappingInfo, HandlerMethod> handlerMethods = handlerMapping.getHandlerMethods();

    String contentPath = Optional.ofNullable(serverProperties).map(ServerProperties::getServlet)
      .map(ServerProperties.Servlet::getContextPath).orElse("");

    List<ApiRequest> list = Lists.newArrayList();
    // 遍历所有映射关系，打印 URL 和对应的方法
    for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : handlerMethods.entrySet()) {
      // 获取 RequestMappingInfo (包含了请求路径信息)
      RequestMappingInfo mappingInfo = entry.getKey();
      HandlerMethod handlerMethod = entry.getValue();
      Logs methodAnnotation = handlerMethod.getMethodAnnotation(Logs.class);
      if (ObjectUtil.isEmpty(methodAnnotation)) {
        continue;
      }
      // 获取所有的 URL 模式
      mappingInfo.getPatternsCondition().getPatterns().forEach(url ->
        mappingInfo.getMethodsCondition().getMethods().forEach(method -> {
          ApiRequest request = new ApiRequest();
          request.setApiType(ApiTypeEnum.PUBLIC);
          request.setAuth(AuthEnum.NEED);
          request.setUrl(contentPath + url);
          request.setTitle(methodAnnotation.title());
          request.setOperation(methodAnnotation.operation());
          request.setMethod(ApiMethodEnum.of(method.name()));
          request.setAppInfoId(systemConfig.getAppInfoId());
          System.out.println("URL: " + url + " --> Handler Method: " + handlerMethod.getMethod().getName());
          list.add(request);
        }));
    }

    try {
      list.forEach(OpenApiClient::openCreateApi);
    } catch (Exception e) {
      log.error("新增api失败: {}", e.getMessage(), e);
    }
  }
}
